package cardCollections;

import java.io.Serializable;
import java.util.ArrayList;

import cards.*;

/**
 * @author tbittma1
 *
 */

/**
 * @author clewis6
 * 
 */
public class Hand implements java.io.Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private ArrayList<Card> playerHand;
	private int handCount;
	private boolean busted;
	private boolean standValue;

	/**
	 * requires: nothing ensures: this.playerHand != null, this.handCount !=
	 * null, this.busted !=null this.standValue != null
	 */
	public Hand() {
		playerHand = new ArrayList<Card>();
		handCount = 0;
		setBusted(false);
	}

	/**
	 * @return the player's hand
	 */
	public ArrayList<Card> getPlayerHand() {
		return playerHand;
	}

	/**
	 * requires:addedCard != null
	 * 
	 * @param addedCard
	 *            ensures: this.playerHand.size = 1+ this.playerHand.size@pre
	 */
	public void AddCard(Card addedCard) {
		playerHand.add(addedCard);
		updateCount(addedCard);
		if (this.handCount > 21 && this.containsAce()) {
			setAces();
		}
		if (this.handCount > 21) {
			this.setBusted(true);
		}

	}

	/**
	 * requires:addedCard != null
	 * 
	 * @param addedCard
	 *            the card to be added
	 * @param index
	 *            the location to add the card
	 */
	public void AddCard(Card addedCard, int index) {
		playerHand.add(index, addedCard);
		updateCount(addedCard);
		if (this.handCount > 21 && this.containsAce()) {
			setAces();
		}
		if (this.handCount > 21) {
			this.setBusted(true);
		}
	}

	/**
	 * requires: addedCard!=null
	 * 
	 * @param addedCard
	 *            ensures nothing
	 */
	private void updateCount(Card addedCard) {
		this.handCount += addedCard.getValue();
	}

	/**
	 * requires: addedCard != null
	 * 
	 * @param addedCard
	 *            ensures:
	 */
	private void setAces() {
		for (int i = 0; i < this.getPlayerHand().size(); i++) {
			if (this.getPlayerHand().get(i).getValue() == 11) {
				Ace temp = (Ace) this.getPlayerHand().get(i);
				this.playerHand.remove(i);
				temp.setAceValue();
				this.handCount -= 11;
				this.AddCard(temp, i);
				break;
			}
		}
	}

	/**
	 * requires: nothing ensures: this.getHandCount == 0, this.PlayerHand.size
	 * == 0
	 */
	public void resetHand() {
		playerHand.clear();
		handCount = 0;
	}

	/**
	 * requires busted != null
	 * 
	 * @param busted
	 *            ensures this.isBusted == busted
	 */
	public void setBusted(boolean busted) {
		this.busted = busted;
	}

	/**
	 * requires: nothing
	 * 
	 * @return this.busted ensures: nothing
	 */
	public boolean isBusted() {
		return busted;
	}

	/**
	 * requires: nothing
	 * 
	 * @return this.handCount ensures:nothing
	 */
	public int getHandCount() {
		return this.handCount;
	}

	/**
	 * requires: standValue!=null
	 * 
	 * @param standValue
	 *            ensures this.getStandValue == standValue
	 */
	public void setStandValue(boolean standValue) {
		this.standValue = standValue;
	}

	/**
	 * requires: nothing
	 * 
	 * @return this.standValue ensures: nothing
	 */
	public boolean isStanding() {
		return standValue;
	}

	/**
	 * requires: nothing
	 * 
	 * @return playerHand.get(1) ensures: this.playerHand.size =
	 *         this.playerHand.size@pre -1
	 */
	public Card removeCard() {
		Card tempCard = playerHand.get(1);
		playerHand.remove(1);
		return tempCard;
	}

	/**
	 * determines if the hand has an ace in it
	 * 
	 * @return the boolean representing if the hand has an ace
	 */
	private boolean containsAce() {
		for (Card c : this.getPlayerHand()) {
			if (c instanceof Ace) {
				return true;
			}
		}
		return false;
	}

	@Override
	public String toString() {
		String s = "";
		for (Card c : playerHand) {
			s += c.toString() + "\n";
		}
		return s;
	}

}
